package com.example.factory.practice;

import lombok.AllArgsConstructor;
import lombok.Data;

public class ChainOfKitchen {
    public static void main(String[] args) {
        SlotChain slotChainA = new SlotChain();
        SlotChain slotChainB = new SlotChain();

        slotChainA.addSlot(new MakeFire()).addSlot(new WashVegetables());
        slotChainB.addSlot(new WashVegetables()).addSlot(new MakeFire());

        slotChainA.addSlot(slotChainB);

        slotChainA.entry(new Content());
    }
}

interface Slot {
    void fireEntry(Content content);

    void entry(Content content);
}

@Data
abstract class AbstractSlot implements Slot {
    AbstractSlot next = null;

    @Override
    public void fireEntry(Content content) {
        if (next != null) {
            next.transport(content);
        }
    }

    public void transport(Content content) {
        entry(content);
    }

}

class MakeFire extends AbstractSlot {

    @Override
    public void entry(Content content) {
        System.out.println("MakeFire start");
        super.fireEntry(content);
        System.out.println("MakeFire end");
    }
}

class WashVegetables extends AbstractSlot {
    @Override
    public void entry(Content content) {
        System.out.println("WashVegetables start");
        super.fireEntry(content);
        System.out.println("WashVegetables end");

    }
}

class SlotChain extends AbstractSlot {
    AbstractSlot first = new AbstractSlot() {
        @Override
        public void entry(Content content) {
            super.fireEntry(content);
        }
    };
    AbstractSlot end = first;

    @Override
    public void entry(Content content) {
        first.fireEntry(content);
    }

    public SlotChain addSlot(AbstractSlot slot) {
        end.setNext(slot);
        end = slot;
        return this;
    }

}

class Content {
    String context;
}
